#ifndef BOOKS_CODE_WINDOWS_COMMON_PCH_H_
#define BOOKS_CODE_WINDOWS_COMMON_PCH_H_

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdint>

#include <iostream>
#include <array>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <deque>
#include <queue>
#include <stack>
#include <string_view>
#include <type_traits>
#include <memory>
#include <random>
#include <limits>

// no copyable
#define TPN_NO_COPYABLE(TypeName)      \
 public:                               \
  TypeName(const TypeName &) = delete; \
  TypeName &operator=(const TypeName &) = delete;

// no moveable
#define TPN_NO_MOVEABLE(TypeName) \
 public:                          \
  TypeName(TypeName &&) = delete; \
  TypeName &operator=(TypeName &&) = delete;

// no implicitable
#define TPN_NO_IMPLICITABLE(TypeName)  \
 private:                              \
  TypeName()                 = delete; \
  TypeName(const TypeName &) = delete; \
  TypeName &operator=(const TypeName &) = delete;

// default copy
#define TPN_DEFAULT_COPY(TypeName)      \
 public:                                \
  TypeName(const TypeName &) = default; \
  TypeName &operator=(const TypeName &) = default;

// default move
#define TPN_DEFAULT_MOVE(TypeName)          \
 public:                                    \
  TypeName(TypeName &&) noexcept = default; \
  TypeName &operator=(TypeName &&) noexcept = default;

// singleton declaration
// xxx.h
// class TypeName {
// TPN_SINGLETON_DECL(TypeName)
//   ...
// }
#define TPN_SINGLETON_DECL(TypeName) \
 public:                             \
  static TypeName *Instance();       \
                                     \
 private:                            \
  TypeName()  = default;             \
  ~TypeName() = default;             \
  TPN_NO_COPYABLE(TypeName)

// singleton implement
// xxx.cpp
// TPN_SINGLETON_IMPL(TypeName)
#define TPN_SINGLETON_IMPL(TypeName) \
  TypeName *TypeName::Instance() {   \
    static TypeName s_instance;      \
    return &s_instance;              \
  }

#endif  // BOOKS_CODE_WINDOWS_COMMON_PCH_H_
